import SyncOutlined from "@ant-design/icons/SyncOutlined"
import { Coupon, CouponService, CouponStatus, CouponType } from "@mallfoundry/marketing/coupon"
import { Button, Card, Col, Divider, Form, Input, Popconfirm, Progress, Row, Select, Space, Table, Tag, Tooltip, Typography } from "antd"
import { ColumnProps } from "antd/lib/table"
import * as _ from "lodash"
import * as React from "react"
import { useEffect, useState } from "react"
import { Link, useHistory, useLocation, useParams } from "react-router-dom"
import Page from "../../components/page"
import { useCoupons } from "../../hooks/coupon"
import { useSearchParams } from "../../hooks/location"
import { messageError } from "../../utils/reason"
import classes from "./coupon-list.module.scss"

const { Title, Text, Link: AntLink } = Typography

interface CouponAddCardProps {
  storeId?: string
  type?: CouponType
  newButton?: boolean
  name: string
  description: React.ReactNode
}

function CouponAddCard(props: CouponAddCardProps) {
  const { storeId, type, newButton = true, name, description } = props

  return (<div className={classes.CouponAddCard}>
    <Space direction="vertical">
      <Title level={5}>{name}</Title>
      <Text>{description}</Text>
      {newButton && <Button type="primary">
        <Link to={{
          pathname: `/stores/${storeId}/coupons/new`,
          search: `type=${type}`,
        }}>立即新建</Link>
      </Button>}
    </Space>
  </div>)
}

function renderCouponType(type: CouponType) {
  if (type === CouponType.FixedDiscount) {
    return "满减券"
  } else if (type === CouponType.PercentageDiscount) {
    return "折扣劵"
  } else if (type === CouponType.RandomDiscount) {
    return "随机金额券"
  } else {
    return ""
  }
}

const BASE_COLUMNS: ColumnProps<Coupon>[] = [
  {
    title: "优惠券名称",
    dataIndex: "name",
    key: "name",
  },
  {
    title: "类型",
    dataIndex: "type",
    key: "type",
    width: "160px",
    align: "center",
    render: renderCouponType,
  },
  {
    title: "优惠内容",
    dataIndex: "type",
    key: "type",
    width: "200px",
    render: (type: CouponType, coupon: Coupon) => {
      const { minAmount, discountAmount, discountPercent, discountMinAmount, discountMaxAmount } = coupon
      const content = [minAmount > 0 ? `满${minAmount}元` : "无门槛"]
      if (type === CouponType.FixedDiscount) {
        content.push(`减${discountAmount}元`)
        return content.join("，")
      } else if (type === CouponType.PercentageDiscount) {
        content.push(`打${discountPercent}折`)
        return content.join("，")
      } else if (type === CouponType.RandomDiscount) {
        content.push(`随机优惠${discountMinAmount}至${discountMaxAmount}元`)
        return content.join("，")
      } else {
        return ""
      }
    },
  },
  {
    title: "状态",
    dataIndex: "status",
    key: "status",
    width: "160px",
    align: "center",
    render: (status: CouponStatus) => {
      if (status === CouponStatus.Pending) {
        return <Tag icon={<SyncOutlined spin/>} color="processing" style={{ marginRight: 0 }}>处理中</Tag>
      } else if (status === CouponStatus.Issuing) {
        return <Tag color="success" style={{ marginRight: 0 }}>发放中</Tag>
      } else if (status === CouponStatus.Paused) {
        return <Tag style={{ marginRight: 0 }}>已失效</Tag>
      } else if (status === CouponStatus.Expired) {
        return <Tag style={{ marginRight: 0 }}>已过期</Tag>
      } else if (status === CouponStatus.Finished) {
        return <Tag style={{ marginRight: 0 }}>已完成</Tag>
      } else {
        return ""
      }
    },
  },
  {
    title: "已领取",
    dataIndex: "receivedCount",
    key: "receivedCount",
    width: "160px",
    align: "center",
  },
  {
    title: "已使用",
    dataIndex: "usedCount",
    key: "usedCount",
    width: "160px",
    align: "center",
  },
  {
    title: "剩余",
    dataIndex: "receivedCount",
    key: "receivedCount",
    width: "160px",
    align: "center",
    render: (receivedCount, { issuingCount }) => {
      const unreceivedCount = issuingCount - receivedCount
      const receivedPercent = receivedCount / issuingCount * 100
      return (
        <Tooltip title={`发放总量：${issuingCount}，剩余：${unreceivedCount}`}>
          <Progress percent={receivedPercent} showInfo={false}
                    size="small" status={receivedPercent === 100 ? "exception" : "active"}/>
        </Tooltip>
      )
    },
  },
]

const filterBarFormLayout = {
  labelCol: { span: 6 },
  wrapperCol: { span: 18 },
}

export default function CouponList() {
  const { storeId } = useParams<{ storeId: string }>()
  const history = useHistory()
  const location = useLocation()
  const searchParams = useSearchParams()
  const page = _.toNumber(searchParams.get("page") ?? 1)
  const limit = _.toNumber(searchParams.get("limit") ?? 20)
  const name = searchParams.get("name") ?? ""
  const types = searchParams.get("types") ?? ""
  const statuses = searchParams.get("statuses") ?? ""
  const timestamp = searchParams.get("timestamp") ?? ""
  const [loading, setLoading] = useState(false)
  const [searchForm] = Form.useForm()

  const {
    loading: couponsLoading,
    totalSize,
    elements: coupons,
  } = useCoupons({
    page, limit,
    name, storeId,
    types, statuses,
    timestamp,
  })

  useEffect(() => {
    searchForm.setFieldsValue({ name, types, statuses })
  }, [searchForm, name, types, statuses])

  const columns: ColumnProps<Coupon>[] = [
    ...BASE_COLUMNS,
    {
      title: "操作",
      dataIndex: "id",
      key: "id",
      width: "160px",
      align: "right",
      render: (id: string, { storeId, status }) => (
        <>
          <Link to={`/stores/${storeId}/coupons/${id}/edit`}>编辑</Link>
          <Divider type="vertical"/>
          <Link to={`/stores/${storeId}/coupons/${id}/copy`}>复制</Link>
          <Divider type="vertical"/>
          {status === CouponStatus.Issuing && <>
            <Popconfirm placement="bottomRight" icon={null} overlayClassName={classes.PauseOverlay}
                        title="活动失效后，无法继续编辑优惠券内容；买家无法再领取该优惠券，但之前已领取的优惠券，在有效期内仍可继续使用。确定失效？"
                        onConfirm={() => {
                          setLoading(true)
                          CouponService.pauseCoupon(id)
                            .catch(messageError)
                            .finally(() => setLoading(false))
                        }}>
              <AntLink>失效</AntLink>
            </Popconfirm>
          </>}
          {status === CouponStatus.Paused && <>
            <Popconfirm placement="bottomRight" icon={null} overlayClassName={classes.PauseOverlay}
                        title="删除后将不可恢复，确定删除？"
                        onConfirm={() => {
                          setLoading(true)
                          CouponService.deleteCoupon(id)
                            .catch(messageError)
                            .finally(() => setLoading(false))
                        }}>
              <AntLink>删除</AntLink>
            </Popconfirm>
          </>}
        </>
      ),
    }]

  function handleReset() {
    history.push(_.assign(location, { search: `` }))
  }

  function handleSearch() {
    searchForm.validateFields()
      .then(values => {
        const { name, statuses, types } = values
        if (name) {
          searchParams.set("name", name)
        } else {
          searchParams.delete("name")
        }
        if (statuses) {
          searchParams.set("statuses", statuses)
        } else {
          searchParams.delete("statuses")
        }
        if (types) {
          searchParams.set("types", types)
        } else {
          searchParams.delete("types")
        }

        searchParams.set("timestamp", Date.now().toString())
        history.replace(_.assign(location, {
          search: `?${searchParams.toString()}`,
        }))
      })
  }

  return (
    <div className={classes.CouponList}>
      <Page.Header title="优惠券" ghost={false}/>
      <Page.Content>
        <Card>
          <Row gutter={[16, 16]}>
            <Col span={4}>
              <CouponAddCard storeId={storeId} type={CouponType.FixedDiscount}
                             name="满减券" description={<>例：满99元减10元<br/>便于合理控制活动成本</>}/>
            </Col>
            <Col span={4}>
              <CouponAddCard storeId={storeId} type={CouponType.PercentageDiscount}
                             name="折扣券" description={<>例：满99元打9折<br/>提高店铺销量和客单价</>}/>
            </Col>
            <Col span={4}>
              <CouponAddCard storeId={storeId} type={CouponType.RandomDiscount}
                             name="随机金额券" description={<>获得金额随机的优惠券<br/>增加活动趣味性</>}/>
            </Col>
          </Row>
          <Row gutter={[16, 16]}>
            <Col span={24}>
              <Card className={classes.FilterBar} bordered={false}>
                <Form {...filterBarFormLayout} form={searchForm}>
                  <Row>
                    <Col span={6}>
                      <Form.Item name="name" label="优惠券名称">
                        <Input placeholder="请输入优惠券名称" allowClear/>
                      </Form.Item>
                    </Col>
                    <Col span={6}>
                      <Form.Item name="types" label="优惠券类型">
                        <Select placeholder="请选择优惠券类型">
                          <Select.Option value="">全部</Select.Option>
                          <Select.Option value={CouponType.FixedDiscount}>满减券</Select.Option>
                          <Select.Option value={CouponType.PercentageDiscount}>折扣券</Select.Option>
                          <Select.Option value={CouponType.RandomDiscount}>随机券</Select.Option>
                        </Select>
                      </Form.Item>
                    </Col>
                    <Col span={6}>
                      <Form.Item name="statuses" label="优惠券状态">
                        <Select placeholder="请选择优惠券状态">
                          <Select.Option value="">全部</Select.Option>
                          <Select.Option value={CouponStatus.Issuing}>发放中</Select.Option>
                          <Select.Option value={CouponStatus.Pending}>处理中</Select.Option>
                          <Select.Option value={CouponStatus.Paused}>已失效</Select.Option>
                          <Select.Option value={CouponStatus.Expired}>已过期</Select.Option>
                          <Select.Option value={CouponStatus.Finished}>已抢光</Select.Option>
                        </Select>
                      </Form.Item>
                    </Col>
                  </Row>
                  <Row>
                    <Col span={6}>
                      <Row>
                        <Col offset={6}>
                          <Space>
                            <Button type="primary" onClick={handleSearch} loading={loading || couponsLoading}>筛选</Button>
                            <Button onClick={handleReset}>重置</Button>
                          </Space>
                        </Col>
                      </Row>
                    </Col>
                  </Row>
                </Form>
              </Card>
            </Col>
          </Row>
          <Row gutter={[16, 16]}>
            <Col span={24}>
              <Table rowKey="id" loading={loading || couponsLoading}
                     columns={columns} dataSource={coupons}
                     pagination={{
                       current: page,
                       pageSize: limit,
                       showSizeChanger: true,
                       pageSizeOptions: ["5", "10", "20", "50", "100"],
                       total: totalSize,
                       showTotal: total => `共 ${total} 条`,
                       onChange: (page, pageSize) => {
                         if (page) {
                           searchParams.set("page", _.toString(page))
                         } else {
                           searchParams.delete("page")
                         }
                         if (pageSize) {
                           searchParams.set("limit", _.toString(pageSize))
                         } else {
                           searchParams.delete("limit")
                         }
                         history.push(_.assign(location, {
                           search: `?${searchParams.toString()}`,
                         }))
                       },
                     }}/>
            </Col>
          </Row>
        </Card>
      </Page.Content>
    </div>
  )
}
